<html t:ref="shell.html">
<li class="active" t:slot="nav2" t:ref=""/>
<div t:slot="body">
    <h4 style="margin-top: 0">1. <b>准备环境</b>
        <small><a href="http://git.oschina.net/kobe2000/webwheel/tree/master/lib">WebWheel及依赖库打包下载</a></small>
    </h4>
    <table class="table table-bordered">
        <tr>
            <th>项目</th>
            <th>版本</th>
            <th>官网</th>
        </tr>
        <tr>
            <td>JRE</td>
            <td>6及以上</td>
            <td><a href="http://www.oracle.com/technetwork/java/index.html">http://www.oracle.com/technetwork/java</a>
            </td>
        </tr>
        <tr>
            <td>Web容器</td>
            <td>servlet 2.3及以上</td>
            <td>
                <a href="http://tomcat.apache.org">http://tomcat.apache.org</a>
                <a href="http://www.eclipse.org/jetty">http://www.eclipse.org/jetty</a>
            </td>
        </tr>
        <tr>
            <td>WebWheel</td>
            <td>1.0</td>
            <td>
                <a href="http://webwheel.sitesmine.com/">http://webwheel.sitesmine.com/</a>
            </td>
        </tr>
        <tr>
            <td>Commons FileUpload</td>
            <td>1.3.1及以上</td>
            <td>
                <a href="http://commons.apache.org/proper/commons-fileupload/">http://commons.apache.org/proper/commons-fileupload/</a>
            </td>
        </tr>
        <tr>
            <td>Jackson</td>
            <td>2.2及以上</td>
            <td>
                <a href="https://github.com/FasterXML/jackson">https://github.com/FasterXML/jackson</a>
            </td>
        </tr>
        <tr>
            <td>MVEL2</td>
            <td>2.1.3及以上</td>
            <td>
                <a href="http://mvel.codehaus.org/">http://mvel.codehaus.org/</a>
            </td>
        </tr>
        <tr>
            <td>ParaNamer</td>
            <td>2.6及以上</td>
            <td>
                <a href="https://github.com/paul-hammant/paranamer">https://github.com/paul-hammant/paranamer</a>
            </td>
        </tr>
    </table>
    <h4>2. <b>设置程序入口</b></h4>

    <p>
        WebWheel使用<a href="www.oracle.com/technetwork/java/filters-137243.html‎">Servlet Filter</a>机制处理web请求及应答，
        所以搭建应用程序的第一步便是在<code>web.xml</code>文件中设置Filter以及指定应用程序入口。
    </p>
    <pre class="prettyprint">&lt;?xml version="1.0" encoding="UTF-8"?>
&lt;web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    &lt;filter>
        &lt;filter-name>WebWheel&lt;/filter-name>
        &lt;!--这里指定webwheel框架的Filter-->
        &lt;filter-class>cn.webwheel.WebWheelFilter&lt;/filter-class>
        &lt;init-param>
            &lt;param-name>main&lt;/param-name>
            &lt;!--指定应用程序的入口类-->
            &lt;param-value><span style="color: red" class="nocode">example1.Main</span>&lt;/param-value>
        &lt;/init-param>
    &lt;/filter>
    &lt;filter-mapping>
        &lt;filter-name>WebWheel&lt;/filter-name>
        &lt;!--过滤所有的地址，可根据需要调整-->
        &lt;url-pattern>/*&lt;/url-pattern>
        &lt;dispatcher>REQUEST&lt;/dispatcher>
        &lt;!--如果需要使用WebWheel内的重定向功能，则必须声明FORWARD类型-->
        &lt;dispatcher>FORWARD&lt;/dispatcher>
    &lt;/filter-mapping>
&lt;/web-app></pre>
    <h4>3. <b>编写入口对象</b></h4>
    <p>
        这里指定了应用程序的入口类为<code>example1.Main</code>。WebWheel框架将在Filter创建时创建此类的一个实例，
        此类必须继承自<code>cn.webwheel.Main</code>抽象类。
    </p>
    <pre class="prettyprint">package example1;
//DefaultMain为cn.webwheel.Main的子类
public class Main extends cn.webwheel.DefaultMain {
    //初始化的地方
    @Override
    protected void init() {
        //调用父类的初始化，包括默认的结果渲染器和参数注入等，必须调用
        super.init();
        //自动扫描example1.web包下的类并映射Action方法
        autoMap("example1.web");
    }
}</pre>
    <p>
        1. <code>cn.webwheel.DefaultMain</code>是<code>cn.webwheel.Main</code>的一个子类，其添加的功能是处理异常的表现，
        使得程序的debug更加简单一些。
    </p>

    <p>
        2. <code>init()</code>方法内放置应用程序的启动代码，包括配置、创建全局资源等等一次性的启动性工作。
    </p>

    <p>
        3. 在<code>Main.init()</code>方法中配置了默认的结果类解释器（包括模板渲染结果类解释器）和参数注入适配器，所以要记住调用
        <code>super.init()</code>方法以获得这些功能。
    </p>

    <p>
        4. <code>autoMap()</code>方法通过扫描类路径的方法，找到动作方法并根据相对包路径映射到URL地址以响应不同地址的HTTP请求。
    </p>

    <div class="comment">
        <p>
            动作方法可以是任意的普通java公开方法，可以是静态或非静态方法，以下的方法签名都可以：
        </p>
    <pre class="prettyprint">public Object execute();
public static String render(String p);
public void filter(String p1, int p2);</pre>
        <p>
            在这些方法上使用注释<code>cn.webwheel.Action</code>进行标注，将使其被<code>autoMap()</code>发现并实现映射。
        </p>

        <p>
            映射的URL路径与包路径一致，web资源的根路径对应于<code>autoMap()</code>的参数包路径。动作方法的名字作为URL的后缀出现。
            例如在某应用中调用<code>autoMap("myapp.web")</code>实现自动映射，映射结果如下：
        </p>
        <pre class="prettyprint">package myapp.web;
public class index {
    @Action
    public Object html() {...} // 映射路径：/index.html
}</pre>
        <pre class="prettyprint">package myapp.web.books;
public class library {
    @Action
    public Object list() {...} // 映射路径：/books/library.list
    @Action
    public Object delete(String id) {...} //映射路径：/books/library.delete
}</pre>
    </div>
    <h4>4. <b>编写动作方法</b></h4>
    <p>
        <code>example1.web</code>包路径下有一个<code>index.java</code>：
    </p>
    <pre class="prettyprint">package example1.web;

import cn.webwheel.Action;
import cn.webwheel.results.RedirectResult;
import cn.webwheel.results.TemplateResult;

public class index {

    public String msg;

    @Action
    public Object html() {//映射URL: /index.html
        //返回模板结果，没有指定模板文件，默认为映射URL
        return new TemplateResult(this);
    }

    @Action
    public Object hello(String name) {//映射URL: /index.hello
        //name为空则重定向到根路径
        if (name.isEmpty()) return new RedirectResult("/");
        msg = "Hello " + name + "!";
        //返回模板结果，指定了模板文件位置，可以是绝对路径，也可以是相对于当前URL的路径
        return new TemplateResult(this, "/index.html");
    }
}</pre>
    <p>
        index类中有两个动作方法：<code>html()</code>和<code>hello()</code>，分别对应URL地址：
        <code>/index.html</code>和<code>/index.hello</code>。HTTP参数可以通过公开属性、setter方法和动作方法参数的形式传递进来，
        在这里<code>html()</code>动作方法接受msg的公开属性代表HTTP参数，<code>hello()</code>动作方法接受name的动作方法参数代表的HTTP参数。
    </p>
    <h4>5. <b>编写页面模板文件</b></h4>
    <p>
        index.html模板文件：
    </p>
    <pre class="prettyprint">&lt;!DOCTYPE html>
&lt;html>
&lt;head lang="en">
    &lt;meta charset="UTF-8">
    &lt;title>Hello WebWheel&lt;/title>
&lt;/head>
&lt;body>
&lt;!--动态输出msg变量-->
&lt;div>&#36;{msg}&lt;/div>
&lt;!--表单提交URL指定到index.hello-->
&lt;form action="index.hello">
    &lt;!--传递name参数到动作方法-->
    name: &lt;input name="name">&lt;input type="submit">
&lt;/form>
&lt;/body>
&lt;/html></pre>
    <p>
        用户在表单中输入名称name，提交表单，框架触发<code>hello()</code>方法，
        业务逻辑中根据参数name是否为空来决定是重定向到根路径，还是设置msg并使用模板渲染。
    </p>
    <div class="comment">
        <p>
            WebWheel的模板文件为格式合法的html文档，可兼容html4/html5/xhtml。标签需要对称关闭，不允许错位。
        </p>
        <p>
            模板中使用<code>&#36;{}</code>或<code>&#35;{}</code>进行表达式输出，前者会根据上下文进行转义特殊字符，后者会按照原始样式显示。
        </p>
        <p>
            模板中使用<code>w:</code>开头的标签属性控制流程化输出，例如与非、循环等。
        </p>
        <p>
            模板中使用<code>t:slot</code>和<code>t:ref</code>标签属性达到模板复用的效果。
        </p>
    </div>
</div>
</html>